package gold.digger;

import gold.utils.InputUtil;

import java.util.*;
import java.util.List;

/**
 * Created by fanzhenyu02 on 2020/6/27.
 * common problem solver template.
 */
public class LC911 {
    public long startExecuteTime = System.currentTimeMillis();

    class TopVotedCandidate {
        // 记录各时间当选者
        TreeMap<Integer, Integer> tree = new TreeMap<>();

        public TopVotedCandidate(int[] persons, int[] times) {
            // 记录当前 全部票数 和 当选者和票数
            HashMap<Integer, Integer> voteMap = new HashMap<>();
            int curWinner = 0, curWinnerVotes = 0;
            // 遍历投票计算结果
            for (int i = 0; i < times.length; i++) {
                voteMap.put(persons[i], voteMap.getOrDefault(persons[i], 0) + 1);
                if (voteMap.get(persons[i]) >= curWinnerVotes) {
                    // 当前最新时刻，票数大于或等于
                    curWinner = persons[i];
                    curWinnerVotes = voteMap.get(persons[i]);
                    tree.put(times[i], curWinner);
                }
            }
        }

        public int q(int t) {
            return tree.floorEntry(t).getValue();
        }
    }


    class TopVotedCandidate_Fail_for_Lost_Condition {

        Map<Integer, HashMap<Integer, Integer>> timeSlotCountMap = new HashMap<>();
        TreeSet<Integer> timeSlotSet = new TreeSet<>();

        public TopVotedCandidate_Fail_for_Lost_Condition(int[] persons, int[] times) {
            for (int i = 0; i < persons.length; i++) {
                timeSlotSet.add(times[i]);

                HashMap<Integer, Integer> curTimeSlotMap;
                if (i == 0) curTimeSlotMap = new LinkedHashMap<>();
                else curTimeSlotMap = new LinkedHashMap<>(timeSlotCountMap.get(times[i - 1]));
                curTimeSlotMap.put(persons[i], curTimeSlotMap.getOrDefault(persons[i], 0) + 1);
                timeSlotCountMap.put(times[i], curTimeSlotMap);
            }
        }

        public int q(int t) {
            Integer closest = timeSlotSet.floor(t);
            final HashMap<Integer, Integer> thatTimeMap = timeSlotCountMap.get(closest);
            int maxCount = 0, maxPerson = 0;
            for (Integer person : thatTimeMap.keySet()) {
                if (thatTimeMap.get(person) > maxCount) {
                    maxCount = thatTimeMap.get(person);
                    maxPerson = person;
                }
            }

            return maxPerson;
        }
    }

    /**
     * Your TopVotedCandidate object will be instantiated and called as such:
     * TopVotedCandidate obj = new TopVotedCandidate(persons, times);
     * int param_1 = obj.q(t);
     */

    public void run() {
        int[] per = InputUtil.toIntegerArray("[0,1,1,0,0,1,0]");
        int[] tim = InputUtil.toIntegerArray("[0,5,10,15,20,25,30]]");
        TopVotedCandidate solution = new TopVotedCandidate(per, tim);
        int[] ss = InputUtil.toIntegerArray("[3,12,25,15,24,8]");
        for (int s : ss) {
            System.out.println(s + " : " + solution.q(s));
        }
    }

    public static void main(String[] args) throws Exception {
        LC911 an = new LC911();
        an.run();

        System.out.println("\ncurrent solution total execute time: " + (System.currentTimeMillis() - an.startExecuteTime) + " ms.");
    }
}
